package com.treetao.union.mall.api.controller;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.IService;
import com.treetao.union.core.id.SnowflakeIdGenerator;
import com.treetao.union.core.redis.RedisLockService;
import com.treetao.union.db.Const;
import com.treetao.union.db.Const.OrderQueryType;
import com.treetao.union.db.Const.OrderRecord;
import com.treetao.union.db.Const.OrderStatus;
import com.treetao.union.db.SettingConvertService;
import com.treetao.union.db.model.MallCouponRecord;
import com.treetao.union.db.model.MallOrder;
import com.treetao.union.db.model.MallOrderDetail;
import com.treetao.union.db.model.MallOrderExpress;
import com.treetao.union.db.model.MallPSku;
import com.treetao.union.db.model.MallSkillSku;
import com.treetao.union.db.model.vo.RestResponse;
import com.treetao.union.db.pojo.SettingTypeOrder;
import com.treetao.union.db.service.MallCartService;
import com.treetao.union.db.service.MallCouponService;
import com.treetao.union.db.service.MallOrderService;
import com.treetao.union.db.service.MallPSkuService;
import com.treetao.union.db.service.MallSkillService;
import com.treetao.union.mall.api.base.BaseCURDController;
import com.treetao.union.mall.api.vo.req.ReqParam;

@RestController
@RequestMapping("/mall/order")
public class MallOrderController extends BaseCURDController {
	@Autowired
	private MallOrderService mallOrderService;
	@Autowired
	private MallPSkuService mallPSkuService;
	@Autowired
	private MallCartService mallCartService;
	@Autowired
	private SettingConvertService settingConvertService;
	@Autowired
	private RedisLockService redisLockService;
	@Autowired
	private MallSkillService mallSkillService;
	@Autowired
	private MallCouponService couponService;

	@Override
	protected IService<?> getCommonService() {
		return mallOrderService;
	}

	/**
	 * 订单详情
	 * 
	 * @param param
	 * @return
	 */
	@GetMapping("detail")
	public RestResponse detail() {
		ReqParam param = getMappingReqParam();
		Long orderno = param.getLong("orderno", false);
		Long userId = getWxuidFromToken();
		MallOrder order = mallOrderService.getMallOrderDetail(orderno, true);
		if (order == null || order.getUserId().longValue() != userId.longValue()) {
			return RestResponse.failure("无权限查看该订单");
		}

		// 下订单后的超时支付时间
		SettingTypeOrder orderTime = settingConvertService.getOrderSetting();
		Map<String, Object> extra = new HashMap<String, Object>();
		extra.put("orderTime", orderTime);
		order.setExts(extra);
		return RestResponse.success(order);
	}

	/**
	 * 确认收货
	 * 
	 * @param param
	 * @return
	 */
	@PostMapping("receive")
	public RestResponse receive(@RequestBody ReqParam param) {
		Long orderno = param.getLong("orderno", false);
		Long userId = getWxuidFromToken();
		MallOrder order = mallOrderService.getMallOrder(orderno);
		if (order == null) {
			return RestResponse.failure("订单不存在");
		} else if (order.getUserId().longValue() != userId.longValue()) {
			return RestResponse.failure("无权限操作该订单");
		} else if (order.getStatus().intValue() != OrderStatus.SEND.getValue()) {
			return RestResponse.failure("该订单不能收货");
		}
		return RestResponse
				.success(mallOrderService.changeOrderStatus(orderno, OrderStatus.RECEIVED_USER, OrderRecord.CANCLE));
	}

	/**
	 * 取消订单
	 * 
	 * @param param
	 * @return
	 */
	@PostMapping("cancle")
	public RestResponse cancle(@RequestBody ReqParam param) {
		Long orderno = param.getLong("orderno", false);
		Long userId = getWxuidFromToken();
		MallOrder order = mallOrderService.getMallOrder(orderno);
		if (order == null) {
			return RestResponse.failure("订单不存在");
		} else if (order.getUserId().longValue() != userId.longValue()) {
			return RestResponse.failure("无权限取消该订单");
		} else if (order.getStatus().intValue() != OrderStatus.CREATE.getValue()) {
			return RestResponse.failure("该订单不能取消");
		}
		return RestResponse
				.success(mallOrderService.changeOrderStatus(orderno, OrderStatus.CANCLE_USER, OrderRecord.CANCLE));
	}

	/**
	 * 创建订单，得做幂等设计 步骤： 1，判断所有SKU是否存在 2，插入到主订单表中 3，插入到订单关联表detail中
	 */
	@PostMapping("create")
	public RestResponse create(@RequestBody ReqParam param) {
		String arrStr = param.getValue("skus", false);// 值为一个JSON数组
		String addrs = param.getValue("addrs", false);// 值为一个JSON对象
		String remark = param.getValue("remark");// 备注
		Long skillId = param.getLong("skillId", true);// 秒杀活动ID
		Long couponId = param.getLong("couponId", true);// 优惠券ID

		Long orderno = SnowflakeIdGenerator.nextId();// 雪花算法，具体按时间排序特性
		Long userId = getWxuidFromToken();
		String payway = Const.PayWay.WEIXIN;
		int status = Const.OrderStatus.CREATE.getValue();

		MallOrder order = new MallOrder();
		order.setRemark(remark);
		order.setOrderno(orderno);
		order.setCreateTime(new Date());
		order.setPayWay(payway);
		order.setUserId(userId);
		order.setStatus(status);
		order.setPriceFreight(0d);// 运费为0

		Double totalPriceTotal = 0d;
		Double totalPriceReal = 0d;
		Integer totalNum = 0;

		try {
			List<MallOrderDetail> details = JSONObject.parseArray(arrStr, MallOrderDetail.class);
			MallOrderExpress express = JSONObject.parseObject(addrs, MallOrderExpress.class);
			if (express == null || StringUtils.isEmpty(express.getUsername())) {
				return RestResponse.failure("请填写收货信息");
			}
			express.setOrderno(orderno);
			order.setExpress(express);
			if (details != null && details.size() > 0) {
				long time = System.currentTimeMillis() + 10 * 1000;// 10秒内只能有一个人抢，处理完则下一个人（秒杀时用到）
				boolean isSkill = false;// 是否秒杀
				Long skuId = 0L;// 秒杀用到
				for (MallOrderDetail detail : details) {
					if (detail.getSkuId() == null) {
						return RestResponse.failure("skuId不能为空");
					}
					if (detail.getSpuId() == null) {
						return RestResponse.failure("spuId不能为空");
					}
					if (detail.getNum() == null) {
						return RestResponse.failure("数量不能为空");
					}
					if (detail.getName() == null) {
						return RestResponse.failure("name不能为空");
					}
					if (detail.getAttrName() == null) {
						return RestResponse.failure("attrName不能为空");
					}
					MallPSku sku = mallPSkuService.getById(detail.getSkuId());
					if (sku == null) {
						return RestResponse.failure("商品不存在");
					}

					if (skillId != null) {// 是秒杀,秒杀只能提交一个商品，所以在这里处理是可以的
						isSkill = true;
						skuId = detail.getSkuId();
						MallSkillSku skillSku = mallSkillService.getSkillSku(skillId, detail.getSkuId());
						if (skillSku == null) {
							return RestResponse.failure("活动已结束");
						}
						if (!redisLockService.tryLock(String.valueOf(detail.getSkuId()), String.valueOf(time))) {
							return RestResponse.failure("抢购人数太多，换个姿势继续抢!");
						}
						Object stockObj = redisService.hget(Const.skillRedisKey, String.valueOf(detail.getSkuId()));
						if (stockObj != null) {
							Integer stock = (Integer) stockObj;
							if (stock <= 0) {
								return RestResponse.failure("已被抢光啦~~");
							}
						}
						// 库存原子递减
						redisService.hdecr(Const.skillRedisKey, String.valueOf(detail.getSkuId()), 1);

						// 秒杀时，算出实际付款价格
						totalPriceReal += skillSku.getSkillPrice() * detail.getNum();
					} else {
						// 实际价格
						totalPriceReal += sku.getPriceSale() * detail.getNum();
					}

					totalPriceTotal += sku.getPriceSale() * detail.getNum();
					detail.setPrice(sku.getPriceSale());// sku对应的价格
					detail.setOrderno(orderno);// 关联订单号
					detail.setImg(sku.getThumbnail());// 图片

					// 数量
					totalNum += detail.getNum();
				}
				
				MallCouponRecord couponRecord = null;
				if (couponId != null) { // 使用了优惠券
					couponRecord = couponService.getMyCanUseCoupon(userId, couponId);
					if(couponRecord.getMan().doubleValue() <= totalPriceTotal.doubleValue()) {
						totalPriceReal = totalPriceTotal - couponRecord.getPrice();
					}
				}
				
				order.setPcount(totalNum);
				order.setPriceReal(totalPriceReal);
				order.setPriceTotal(totalPriceTotal);

				boolean flag = mallOrderService.createOrder(order, details);
				if (flag) {
					if (isSkill) {
						// 秒杀处理完成后，释放锁
						redisLockService.unlock(String.valueOf(skuId), String.valueOf(time));
					} else {
						// 从购物车删除
						mallCartService.removeUserCart(userId, details.stream().map(item -> item.getSkuId()).toArray());
					}
					
					if(couponRecord!=null && couponId!=null && couponRecord.getMan().doubleValue() <= totalPriceTotal.doubleValue()) {
						//优惠券置为已使用
						couponService.setCouponUsed(userId,couponId);
					}

					return RestResponse.success(orderno);// 下单成功后，返回订单号
				} else {
					return RestResponse.failure("订单创建失败");
				}
			} else {
				return RestResponse.failure("请选择至少一个商品");
			}
		} catch (Exception e) {
			return RestResponse.failure("参数错误," + e.getMessage());
		}
	}

	@GetMapping("list")
	public RestResponse list() {
		Long userId = getWxuidFromToken();
		ReqParam param = getMappingReqParam();
		String type = param.getValue("type") == null ? OrderQueryType.ALL : param.getValue("type");
		List<MallOrder> orders = mallOrderService.getMallOrderList(userId, param.getPageCurrent(), param.getPageSize(),
				type);
		return RestResponse.success(orders);
	}
}
